<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Jobs\SyncBankDetailsJob;
use App\Models\BankDetailHangzhou;
use App\Models\LandingCompany;
use App\Models\Recharge;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;

class AdminBankDetailController extends Controller
{
    /**
     * 获取银行明细列表
     * GET /admin/bank-details
     */
    public function index(Request $request): JsonResponse
    {
        try {
            $query = BankDetailHangzhou::with(['recharge', 'matchedBy'])
                ->orderBy('transaction_datetime', 'desc');

            // 匹配状态筛选
            if ($request->filled('match_status')) {
                $status = $request->get('match_status');
                if (is_array($status)) {
                    $query->whereIn('match_status', $status);
                } else {
                    $query->where('match_status', $status);
                }
            }

            // 收支类型筛选
            if ($request->filled('cd_sign')) {
                $query->where('cd_sign', $request->get('cd_sign'));
            }

            // 金额范围筛选
            if ($request->filled('amount_min')) {
                $query->where('amt', '>=', $request->get('amount_min'));
            }
            if ($request->filled('amount_max')) {
                $query->where('amt', '<=', $request->get('amount_max'));
            }

            // 时间范围筛选
            if ($request->filled('date_start')) {
                $query->whereDate('trans_date', '>=', $request->get('date_start'));
            }
            if ($request->filled('date_end')) {
                $query->whereDate('trans_date', '<=', $request->get('date_end'));
            }

            // 搜索：流水号、对方户名、对方账号、银行名称、摘要
            if ($request->filled('search')) {
                $search = $request->get('search');
                $query->where(function ($q) use ($search) {
                    $q->where('serial_no', 'like', "%{$search}%")
                      ->orWhere('opp_acc_name', 'like', "%{$search}%")
                      ->orWhere('opp_acc_no', 'like', "%{$search}%")
                      ->orWhere('opp_acc_bank', 'like', "%{$search}%")
                      ->orWhere('abs', 'like', "%{$search}%");
                });
            }

            // 分页
            $perPage = $request->get('per_page', 20);
            $details = $query->paginate($perPage);

            // 添加统计信息
            $statistics = [
                'match_status_counts' => BankDetailHangzhou::selectRaw('match_status, COUNT(*) as count')
                    ->groupBy('match_status')
                    ->pluck('count', 'match_status')
                    ->toArray(),
                'cd_sign_counts' => BankDetailHangzhou::selectRaw('cd_sign, COUNT(*) as count')
                    ->groupBy('cd_sign')
                    ->pluck('count', 'cd_sign')
                    ->toArray(),
                'total_amount' => BankDetailHangzhou::where('cd_sign', '0')->sum('amt'), // 收入总额
                'today_count' => BankDetailHangzhou::whereDate('trans_date', today())->count(),
            ];

            return response()->json([
                'code' => 0,
                'message' => '获取成功',
                'data' => [
                    'list' => $details->items(),
                    'pagination' => [
                        'current_page' => $details->currentPage(),
                        'per_page' => $details->perPage(),
                        'total' => $details->total(),
                        'last_page' => $details->lastPage(),
                    ],
                    'statistics' => $statistics
                ]
            ]);

        } catch (\Exception $e) {
            Log::error('获取银行明细列表失败', [
                'error' => $e->getMessage(),
                'params' => $request->all()
            ]);

            return response()->json([
                'code' => 500,
                'message' => '获取银行明细列表失败',
                'data' => null
            ], 500);
        }
    }

    /**
     * 获取银行明细详情
     * GET /admin/bank-details/{id}
     */
    public function show($id): JsonResponse
    {
        try {
            $detail = BankDetailHangzhou::with(['recharge', 'matchedBy'])->find($id);

            if (!$detail) {
                return response()->json([
                    'code' => 404,
                    'message' => '银行明细不存在',
                    'data' => null
                ], 404);
            }

            // 获取匹配建议（如果未匹配）
            $matchSuggestions = [];
            if ($detail->match_status === 'unmatched') {
                $matchSuggestions = $this->getMatchSuggestions($detail);
            }

            return response()->json([
                'code' => 0,
                'message' => '获取成功',
                'data' => [
                    'detail' => $detail,
                    'match_suggestions' => $matchSuggestions
                ]
            ]);

        } catch (\Exception $e) {
            Log::error('获取银行明细详情失败', [
                'error' => $e->getMessage(),
                'detail_id' => $id
            ]);

            return response()->json([
                'code' => 500,
                'message' => '获取银行明细详情失败',
                'data' => null
            ], 500);
        }
    }

    /**
     * 获取匹配建议
     * GET /admin/bank-details/{id}/match-suggestions
     */
    public function matchSuggestions($id): JsonResponse
    {
        try {
            $detail = BankDetailHangzhou::find($id);

            if (!$detail) {
                return response()->json([
                    'code' => 404,
                    'message' => '银行明细不存在',
                    'data' => null
                ], 404);
            }

            if ($detail->match_status !== 'unmatched') {
                return response()->json([
                    'code' => 400,
                    'message' => '该明细已处理，无需匹配建议',
                    'data' => []
                ]);
            }

            $suggestions = $this->getMatchSuggestions($detail);

            return response()->json([
                'code' => 0,
                'message' => '获取成功',
                'data' => $suggestions
            ]);

        } catch (\Exception $e) {
            Log::error('获取匹配建议失败', [
                'error' => $e->getMessage(),
                'detail_id' => $id
            ]);

            return response()->json([
                'code' => 500,
                'message' => '获取匹配建议失败',
                'data' => null
            ], 500);
        }
    }

    /**
     * 更新银行明细状态
     * PUT /admin/bank-details/{id}/status
     */
    public function updateStatus(Request $request, $id): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'status' => 'required|in:unmatched,matched,ignored',
            'reason' => 'nullable|string|max:500'
        ]);

        if ($validator->fails()) {
            return response()->json([
                'code' => 400,
                'message' => '参数验证失败',
                'data' => $validator->errors()
            ], 400);
        }

        try {
            $detail = BankDetailHangzhou::find($id);

            if (!$detail) {
                return response()->json([
                    'code' => 404,
                    'message' => '银行明细不存在',
                    'data' => null
                ], 404);
            }

            $newStatus = $request->get('status');
            $reason = $request->get('reason');
            $operatorId = auth()->id();

            // 处理不同状态的更新
            switch ($newStatus) {
                case 'ignored':
                    $success = $detail->markAsIgnored($operatorId);
                    break;

                case 'unmatched':
                    $success = $detail->unmatch();
                    break;

                default:
                    return response()->json([
                        'code' => 400,
                        'message' => '不支持的状态更新操作',
                        'data' => null
                    ], 400);
            }

            if ($success) {
                // 记录操作日志
                Log::info('银行明细状态更新', [
                    'detail_id' => $id,
                    'old_status' => $detail->getOriginal('match_status'),
                    'new_status' => $newStatus,
                    'operator_id' => $operatorId,
                    'reason' => $reason
                ]);

                return response()->json([
                    'code' => 0,
                    'message' => '状态更新成功',
                    'data' => [
                        'detail_id' => $id,
                        'new_status' => $newStatus
                    ]
                ]);
            } else {
                return response()->json([
                    'code' => 400,
                    'message' => '状态更新失败',
                    'data' => null
                ], 400);
            }

        } catch (\Exception $e) {
            Log::error('更新银行明细状态失败', [
                'error' => $e->getMessage(),
                'detail_id' => $id,
                'status' => $request->get('status')
            ]);

            return response()->json([
                'code' => 500,
                'message' => '更新银行明细状态失败',
                'data' => null
            ], 500);
        }
    }

    /**
     * 批量更新明细状态
     * POST /admin/bank-details/batch-update-status
     */
    public function batchUpdateStatus(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'detail_ids' => 'required|array',
            'detail_ids.*' => 'integer|exists:bank_details_hangzhou,id',
            'status' => 'required|in:ignored,unmatched',
            'reason' => 'nullable|string|max:500'
        ]);

        if ($validator->fails()) {
            return response()->json([
                'code' => 400,
                'message' => '参数验证失败',
                'data' => $validator->errors()
            ], 400);
        }

        try {
            $detailIds = $request->get('detail_ids');
            $newStatus = $request->get('status');
            $reason = $request->get('reason');
            $operatorId = auth()->id();

            $successCount = 0;
            $failedCount = 0;
            $results = [];

            foreach ($detailIds as $detailId) {
                try {
                    $detail = BankDetailHangzhou::find($detailId);

                    if (!$detail) {
                        $results[] = [
                            'detail_id' => $detailId,
                            'success' => false,
                            'error' => '明细不存在'
                        ];
                        $failedCount++;
                        continue;
                    }

                    $success = false;
                    switch ($newStatus) {
                        case 'ignored':
                            $success = $detail->markAsIgnored($operatorId);
                            break;
                        case 'unmatched':
                            $success = $detail->unmatch();
                            break;
                    }

                    if ($success) {
                        $successCount++;
                        $results[] = [
                            'detail_id' => $detailId,
                            'success' => true,
                            'error' => null
                        ];
                    } else {
                        $failedCount++;
                        $results[] = [
                            'detail_id' => $detailId,
                            'success' => false,
                            'error' => '状态更新失败'
                        ];
                    }

                } catch (\Exception $e) {
                    $failedCount++;
                    $results[] = [
                        'detail_id' => $detailId,
                        'success' => false,
                        'error' => $e->getMessage()
                    ];
                }
            }

            Log::info('批量更新银行明细状态', [
                'detail_ids' => $detailIds,
                'new_status' => $newStatus,
                'operator_id' => $operatorId,
                'reason' => $reason,
                'success_count' => $successCount,
                'failed_count' => $failedCount
            ]);

            return response()->json([
                'code' => 0,
                'message' => "批量更新完成，成功 {$successCount}/{count($detailIds)} 项",
                'data' => [
                    'total' => count($detailIds),
                    'success_count' => $successCount,
                    'failed_count' => $failedCount,
                    'results' => $results
                ]
            ]);

        } catch (\Exception $e) {
            Log::error('批量更新银行明细状态失败', [
                'error' => $e->getMessage(),
                'detail_ids' => $request->get('detail_ids')
            ]);

            return response()->json([
                'code' => 500,
                'message' => '批量更新银行明细状态失败',
                'data' => null
            ], 500);
        }
    }

    /**
     * 获取匹配建议
     */
    private function getMatchSuggestions(BankDetailHangzhou $detail, int $limit = 5): array
    {
        try {
            // 只为收入明细提供匹配建议
            if ($detail->cd_sign !== '0') {
                return [];
            }

            // 获取待匹配的充值申请
            $pendingRecharges = Recharge::whereIn('status', [
                Recharge::STATUS_PENDING,
                Recharge::STATUS_PROCESSING
            ])->orderBy('created_at', 'desc')
              ->limit(50)
              ->get();

            $suggestions = [];

            foreach ($pendingRecharges as $recharge) {
                // 简化的匹配度计算
                $confidence = $this->calculateSimpleConfidence($recharge, $detail);

                if ($confidence >= 0.3) { // 最低阈值
                    $suggestions[] = [
                        'recharge' => $recharge,
                        'confidence' => round($confidence, 3),
                        'match_reasons' => $this->getMatchReasons($recharge, $detail, $confidence)
                    ];
                }
            }

            // 按置信度排序并限制数量
            usort($suggestions, function ($a, $b) {
                return $b['confidence'] <=> $a['confidence'];
            });

            return array_slice($suggestions, 0, $limit);

        } catch (\Exception $e) {
            Log::error('获取匹配建议失败', [
                'error' => $e->getMessage(),
                'detail_id' => $detail->id
            ]);
            return [];
        }
    }

    /**
     * 简化的置信度计算
     */
    private function calculateSimpleConfidence(Recharge $recharge, BankDetailHangzhou $detail): float
    {
        $score = 0;

        // 金额匹配 (40%)
        if ($recharge->amount == $detail->amt) {
            $score += 0.4;
        } elseif (abs($recharge->amount - $detail->amt) / max($recharge->amount, $detail->amt) <= 0.05) {
            $score += 0.2;
        }

        // 时间匹配 (30%)
        $timeDiff = abs($recharge->created_at->diffInHours($detail->transaction_datetime));
        if ($timeDiff <= 1) {
            $score += 0.3;
        } elseif ($timeDiff <= 24) {
            $score += 0.2;
        } elseif ($timeDiff <= 72) {
            $score += 0.1;
        }

        // 银行账号匹配 (20%)
        if ($recharge->bank_account && $recharge->bank_account === $detail->bank_acc) {
            $score += 0.2;
        }

        // 银行名称匹配 (10%)
        if ($recharge->bank_name && $detail->opp_acc_bank &&
            strpos($detail->opp_acc_bank, $recharge->bank_name) !== false) {
            $score += 0.1;
        }

        return $score;
    }

    /**
     * 获取匹配原因说明
     */
    private function getMatchReasons(Recharge $recharge, BankDetailHangzhou $detail, float $confidence): array
    {
        $reasons = [];

        if ($recharge->amount == $detail->amt) {
            $reasons[] = '金额完全匹配';
        } elseif (abs($recharge->amount - $detail->amt) <= 5) {
            $reasons[] = '金额接近匹配';
        }

        $timeDiff = abs($recharge->created_at->diffInHours($detail->transaction_datetime));
        if ($timeDiff <= 1) {
            $reasons[] = '时间非常接近';
        } elseif ($timeDiff <= 24) {
            $reasons[] = '时间较为接近';
        }

        if ($recharge->bank_account === $detail->bank_acc) {
            $reasons[] = '银行账号匹配';
        }

        if ($confidence >= 0.8) {
            $reasons[] = '高置信度匹配';
        } elseif ($confidence >= 0.6) {
            $reasons[] = '中等置信度匹配';
        }

        return $reasons;
    }

    /**
     * 触发银行明细同步任务
     */
    public function sync(Request $request): JsonResponse
    {
        $landingCompany = LandingCompany::active()->orderBy('id')->first();

        if (! $landingCompany || empty($landingCompany->account_number)) {
            return response()->json([
                'code' => 422,
                'message' => '未找到有效的落地公司银行账号，无法触发同步',
                'data' => null,
            ], 422);
        }

        SyncBankDetailsJob::dispatch($landingCompany->account_number);

        return response()->json([
            'code' => 0,
            'message' => '银行明细同步任务已提交，请稍后刷新查看结果',
            'data' => null,
        ]);
    }
}
